/* Compile with: gcc omoctl.c -o omoctl -lcli */
/* Requires the libcli library */
/* After launching, telnet to port 12345 to play with it */

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <libcli.h>

int cmd_test(struct cli_def *cli, char *command, char *argv[], int argc)
{
    cli_print(cli, "called %s with %s\r\n", __FUNCTION__, command);
    return CLI_OK;
}

int cmd_set(struct cli_def *cli, char *command, char *argv[], int argc)
{
    if (argc < 2)
    {
	cli_print(cli, "Specify a variable to set\r\n");
	return CLI_OK;
    }
    cli_print(cli, "Setting %s to %s\r\n", argv[0], argv[1]);
    return CLI_OK;
}

int
cmd_show_session(struct cli_def *cli, char *command, char*argv[], int argc) {
    if (argc < 1)
    {
	cli_print(cli, "Specify a session to list\r\n");
	return CLI_OK;
    }
    cli_print(cli, "session %s {", argv[0]);
    cli_print(cli, "    created: Jan 1, 2008 11:01:01");
    cli_print(cli, "    client ip: 192.168.10.10");
    cli_print(cli, "    client port: 65021");
    cli_print(cli, "    interval: 45");
    cli_print(cli, "    number of messages sent: xxx");
    cli_print(cli, "    proxy {");
    cli_print(cli, "        host 192.168.1.1");
    cli_print(cli, "        forwarded requests: xxx");
    cli_print(cli, "        cookies {");
    cli_print(cli, "            mysession {");
    cli_print(cli, "                value: 2353b42cd23523423f");
    cli_print(cli, "                expires: xxx");
    cli_print(cli, "            }");
    cli_print(cli, "            user {");
    cli_print(cli, "                value: dwhite");
    cli_print(cli, "            }");
    cli_print(cli, "        }");
    cli_print(cli, "    }");
    cli_print(cli, "}");
    return CLI_OK;
}

int main(int argc, char *argv[])
{
	struct sockaddr_in servaddr;
	struct cli_command *c, *d;
	struct cli_def *cli;
	int on = 1, x, s;

	// Must be called first to setup data structures
	cli = cli_init();

	// Set the hostname (shown in the the prompt)
	cli_set_hostname(cli, "test");

	// Set the greeting
	cli_set_banner(cli, "Welcome to the CLI test program.");

	// Enable 2 username / password combinations
	//cli_allow_user(cli, "fred", "nerk");
	//cli_allow_user(cli, "foo", "bar");

	// Set up a few simple one-level commands
	//cli_register_command(cli, NULL, "test", cmd_test, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
	//cli_register_command(cli, NULL, "simple", cmd_test, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
	//cli_register_command(cli, NULL, "simon", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);

	// This command takes arguments, and requires privileged mode (enable)
	cli_register_command(cli, NULL, "set", cmd_set, PRIVILEGE_PRIVILEGED, MODE_EXEC, NULL);

	// Set up 2 commands "show counters" and "show junk"
	c = cli_register_command(cli, NULL, "show", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
	// Note how we store the previous command and use it as the parent for this one.
	//cli_register_command(cli, c, "session", cmd_test, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
	// This one has some help text
	//d = cli_register_command(cli, c, "session", cmd_test, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "session help");
	d = cli_register_command(cli, c, "session", cmd_show_session, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "session help");
	cli_register_command(cli, c, "cookie", cmd_test, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "cookie");

	// Create a socket
	s = socket(AF_INET, SOCK_STREAM, 0);
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	// Listen on port 12345
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(12345);
	bind(s, (struct sockaddr *)&servaddr, sizeof(servaddr));

	// Wait for a connection
	listen(s, 50);

	while ((x = accept(s, NULL, 0)))
	{
		// Pass the connection off to libcli
		cli_loop(cli, x);
		close(x);
	}

	// Free data structures
	cli_done(cli);

	return 0;
}

